import json
from base64 import b64decode
import logging
import tornado.web
from tornado.web import Finish
import datetime


class DateEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            return obj.strftime("%Y-%m-%d %H:%M:%S")
        elif isinstance(obj, datetime.date):
            return obj.strftime("%Y-%m-%d")

        return json.JSONEncoder.default(self, obj)


class BaseHandler(tornado.web.RequestHandler):
    def prepare(self):
        authorization = self.request.headers.get("authorization", None)
        if authorization is None:
            log_text = "认证信息缺失"
            logging.error(log_text)
            self.set_status(401)
            self.set_header('WWW-Authenticate', 'Basic realm="Basic"')
            self.write(log_text.encode())
            raise Finish()

        authorization_list = authorization.split(" ")
        if len(authorization_list) != 2:
            log_text = "认证信息格式错误[%s]" % authorization
            logging.error(log_text)
            self.set_status(401)
            self.set_header('WWW-Authenticate', 'Basic realm="Basic"')
            self.write(log_text.encode())
            raise Finish()
        scheme = authorization_list[0]
        param = authorization_list[1]
        if scheme != "Basic":
            log_text = "不支持的认证协议[%s]" % scheme
            logging.error(log_text)
            self.set_status(401)
            self.set_header('WWW-Authenticate', 'Basic realm="Basic"')
            self.write(log_text.encode())
            raise Finish()

        try:
            data = b64decode(param).decode("ascii")
        except Exception as ex:
            log_text = "认证信息解码异常[%s]" % ex
            logging.error(log_text)
            self.set_status(401)
            self.set_header('WWW-Authenticate', 'Basic realm="Basic"')
            self.write(log_text.encode())
            raise Finish()

        username, password = data.split(":")
        if username != "admin" or password != "111111":
            log_text = "用户名或密码错误"
            logging.error(log_text)
            self.set_status(401)
            self.set_header('WWW-Authenticate', 'Basic realm="Basic"')
            self.write(log_text.encode())
            raise Finish()

        return None

    def set_response(self, data, status=200):
        self.set_status(status)
        if isinstance(data, bytes):
            self.set_header("Content-Type", "octet-stream")
            self.set_header("Content-Length", len(data))
            self.write(data)
        elif isinstance(data, dict):

            body = json.dumps(data, ensure_ascii=False, cls=DateEncoder)

            self.set_header("Content-Type", "application/json")
            self.set_header("Content-Length", len(body.encode()))
            self.write(body.encode())
        elif isinstance(data, str):
            self.set_header("Content-Type", "text/plain")
            self.set_header("Content-Length", len(data.encode()))
            self.write(data.encode())
        else:
            data = str(data)
            self.set_header("Content-Type", "text/plain")
            self.set_header("Content-Length", len(data.encode()))
            self.write(data.encode())
        self.finish()
